<template>
    <div id="app"
         @mouseup="control($event,'up')"
         @mousemove="drag($event)"
         @mousedown="control($event,'down')"
         @touchend="control($event,'up')"
         @touchmove="drag($event)"
         @touchstart="control($event,'down')">
        <div class="top" v-if="percent>0.98" transition="top"><img src="assets/Aries.png"></div>
        <canvas :width="canvas.width" :height="canvas.height"></canvas>
    </div>
</template>

<script type="text/babel">
    let {P, init} = require('./class/Point');
    let {Cube} = require('./class/Cube');
    let {Aries, Rec} = require('./assets/Zodiacs');
    let {Zodiac} = require('./class/Zodiac');

    let canvas = null;
    let randomSpeed = 5;
    let scale = 1 / 50;
    let w = 400;
    let h = 400;

    var focus = P(3000, 0, 0);
    var f = 1000;
    var starsMax = 200;
    var CubeLength = 1000;

    init({
        canvasWidth: w,
        canvasHeight: h,
        focalLength: f,
        focus: focus
    });

    var Box = new Cube(CubeLength);

    var Aries_Rec = new Zodiac({
        range: CubeLength / 2,
        ...Aries
    });

    //创造星云
    var StarsCloud = [];
    for (let i = 0; i < starsMax; i++) {
        StarsCloud.push(P(
                Math.floor(Math.random() * CubeLength - CubeLength / 2),
                Math.floor(Math.random() * CubeLength - CubeLength / 2),
                Math.floor(Math.random() * CubeLength - CubeLength / 2)
        ))
    }

    //根据顺序获取星星渲染时的参数
    let getStarPorperty = (precent)=> {
        let Cmin = [104, 215, 137];
        let Cmax = [250, 255, 111];
        let Ccom = Cmin.map((c, i)=> {
            return Math.floor(-precent * (Cmax[i] - c)) + Cmax[i];
        });
        return {
            color: `rgba(${Ccom[0]},${Ccom[1]},${Ccom[2]},${-precent * 0.7 + 1})`
        }
    };

    export default {
        data: ()=> ({
            isDrag: false,
            x: 0, y: 0,
            xa: 0, ya: 0,
            isChange: false,
            isPrevent: false,
            percent: 0,
            canvas: {
                width: `${w}px`,
                height: `${h}px`
            }
        }),
        methods: {
            spinX: function (a) {
                Box.vertexs.forEach((p)=> {
                    p.turnX(a);
                });
                StarsCloud.forEach((p)=> {
                    p.turnX(a);
                });
                Aries_Rec.turnX(a);
            },
            spinY: function (a) {
                Box.vertexs.forEach((p)=> {
                    p.turnY(a);
                });
                StarsCloud.forEach((p)=> {
                    p.turnY(a);
                });
                Aries_Rec.turnY(a);
            },
            draw: function () {
                canvas.clearRect(0, 0, w, h);
                canvas.fillStyle = "rgb(13,13,13)";
                canvas.fillRect(0, 0, 400, 400);

                Box.edges.sort((a, b)=> {
                    return a.r < b.r
                }).forEach((edge, i)=> {
                    let p1 = edge.a.toCanvas();
                    let p2 = edge.b.toCanvas();
                    let color = Math.floor(-(i / 11) * (20 - 30) + 30);

                    canvas.strokeStyle = `rgb(${color},${color},${color})`;
                    canvas.beginPath();
                    canvas.moveTo(p1.x, p1.y);
                    canvas.lineTo(p2.x, p2.y);
                    canvas.closePath();
                    canvas.stroke();
                });

                StarsCloud.sort((a, b)=>a.r > b.r);

                StarsCloud.forEach((p, i)=> {
                    let canvasPoint = p.toCanvas();
                    let star = getStarPorperty(i / starsMax);
                    canvas.fillStyle = star.color;
                    canvas.beginPath();
                    canvas.arc(canvasPoint.x, canvasPoint.y, -i / starsMax + 2, 0, Math.PI * 2);
                    canvas.closePath();
                    canvas.fill();
                });

                // console.log(Aries_Rec.precent);
                let pc = Aries_Rec.precent;
                Aries_Rec.lines.forEach((edge)=> {
                    let p1 = edge.a.toCanvas();
                    let p2 = edge.b.toCanvas();
                    if (pc > 0.98) {
                        canvas.strokeStyle = `rgb(200,200,200)`;
                    } else {
                        canvas.strokeStyle = `rgb(30,30,30)`;
                    }

                    canvas.beginPath();
                    canvas.moveTo(p1.x, p1.y);
                    canvas.lineTo(p2.x, p2.y);
                    canvas.closePath();
                    canvas.stroke();
                });

                Aries_Rec.nodes.forEach((p)=> {
                    let canvasPoint = p.toCanvas();
                    canvas.fillStyle = `rgba(255,255,255,${pc * 0.5 + 0.5})`;
                    canvas.beginPath();
                    if (pc > 0.60) {
                        canvas.shadowOffsetX = 0;
                        canvas.shadowOffsetY = 0;
                        canvas.shadowColor = `rgba(255,255,255,${(pc - 0.6) / 0.4})`;
                        canvas.shadowBlur = 5 * (pc - 0.6) / 0.4;
                    }
                    canvas.arc(canvasPoint.x, canvasPoint.y, pc * 4, 0, Math.PI * 2);
                    canvas.closePath();
                    canvas.fill();
                });
                canvas.shadowOffsetX = 0;
                canvas.shadowOffsetY = 0;
                canvas.shadowColor = 'rgba(255,255,255,0.5)';
                canvas.shadowBlur = 0;

            },
            fix: function () {
                Box.vertexs.forEach((p)=> {
                    p.save();
                });
                StarsCloud.forEach((p)=> {
                    p.save();
                });
            },
            drag: function ($event) {
                $event.preventDefault();
                if (!this.isDrag || this.isPrevent)return;
                let {abs} = Math;
                let dx = ($event.clientX || $event.touches[0].clientX) - this.x;
                let dy = ($event.clientY || $event.touches[0].clientY) - this.y;
                if (abs(dx) > 0) {
                    this.spinX(dx * scale);
                    this.fix();
                }
                if (abs(dy) > 0) {
                    this.spinY(dy * scale);
                    this.fix();
                }
                this.percent = Aries_Rec.precent;
                this.isChange = true;
                this.x = $event.clientX || $event.touches[0].clientX;
                this.y = $event.clientY || $event.touches[0].clientY;
            },
            control: function ($event, event) {
                if (event == 'down') {
                    this.isDrag = true;
                    this.x = $event.clientX || $event.touches[0].clientX;
                    this.y = $event.clientY || $event.touches[0].clientY;
                } else if (event == 'up') {
                    this.isDrag = false;
                }
            }
        },
        ready: function () {
            canvas = [...this.$el.children].filter((n)=> {
                return n.localName == 'canvas'
            })[0].getContext('2d');
            window.canvas = canvas;
            this.isChange = true;

            let vm = this;
            let Render = ()=> {
                if (!vm.isChange) {
                    return window.AnimeRender(Render);
                } else {
                    vm.draw();
                    vm.isChange = false;
                    window.AnimeRender(Render);
                }
            };
            window.AnimeRender(Render);

            // setInterval(()=>{
            //     vm.isChange = true;
            //     StarsCloud.forEach((v)=>{

            //         let gv = ()=>{
            //             return (Math.random()-0.5) * randomSpeed;
            //         }

            //         v.move(gv(),gv(),gv());
            //         v.save();
            //     });
            // },30)

            window.complete = ()=> {
                Aries_Rec.ResetX((rX)=> {
                    let {abs} = Math;
                    if (abs(rX) > 1e-3) {
                        vm.spinX(rX);
                        vm.fix();
                    }
                    this.isChange = true;
                });
                Aries_Rec.ResetY((rY)=> {
                    let {abs} = Math;
                    if (abs(rY) > 1e-3) {
                        vm.spinY(rY);
                        vm.fix();
                    }
                    console.log(Aries_Rec.anwser.x, Aries_Rec.anwser.y, Aries_Rec.anwser.z);
                    this.isChange = true;
                });
            };
        }
    }
</script>

<style>
    html {
        height: 100%;
        background: rgb(13, 13, 13);
    }

    .top {
        position: absolute;
        top: 0;
        width: 100%;
        transition: all 0.5s;
        text-align: center;
    }

    .top-transition {
        opacity: 1;
    }

    .top-enter, .top-leave {
        opacity: 0;

    }

    body {
        display: flex;
        align-items: center;
        justify-content: center;
        height: 100%;
    }

    #app {
        width: 100%;
        height: 100%;
        position: fixed;
        top: 0;
        left: 0;
        color: #2c3e50;
        font-family: Source Sans Pro, Helvetica, sans-serif;
        text-align: center;
    }

    #app > canvas {
        margin-top: 100px;
        max-width: 600px;
        width: 100%;
    }

    #app a {
        color: #42b983;
        text-decoration: none;
    }

    .logo {
        width: 100px;
        height: 100px
    }
</style>